package co.gov.medellin.ssti.sub.service;

import java.io.UnsupportedEncodingException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Collection;

import javax.naming.NamingException;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;

import co.gov.medellin.ssti.sub.common.ConexionFactory;
import co.gov.medellin.ssti.sub.common.dao.TransactionUtil;
import co.gov.medellin.ssti.sub.common.excepcion.SUBException;
import co.gov.medellin.ssti.sub.model.dao.DAOFactory;
import co.gov.medellin.ssti.sub.model.dao.ICargueDAO;
import co.gov.medellin.ssti.sub.model.dao.exception.DAOException;
import co.gov.medellin.ssti.sub.model.vo.CargueVO;
import co.gov.medellin.ssti.sub.model.vo.RegNoProcesadosVO;

public class CargueService {
	/**
	 * 
	 * @param criteria
	 * @return
	 * @throws SQLException
	 */
	public Collection<CargueVO> findArchivoCargueByCriteria(CargueVO criteria)
			throws DAOException {
		ICargueDAO cargueDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			cargueDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getCargueDAO(con);
			return cargueDAO.findArchivoCargueByCriteria(criteria);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (cargueDAO != null) {
				if (!cargueDAO.isConnClosed()) {
					cargueDAO.close();
				}
			}
		}
	}

	/**
	 * 
	 * @param codeLote
	 * @return
	 * @throws SQLException
	 */
	public String[] findTotalRegistrosByCodigoLote(String codeLote)
			throws DAOException {
		ICargueDAO cargueDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			cargueDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getCargueDAO(con);
			return cargueDAO.findTotalRegistrosByCodigoLote(codeLote);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (cargueDAO != null) {
				if (!cargueDAO.isConnClosed()) {
					cargueDAO.close();
				}
			}
		}
	}

	/**
	 * 
	 * @param criterea
	 * @param user
	 * @param terminal
	 * @param fecha
	 * @return
	 * @throws SQLException
	 */
	public String[] ingresarCargue(CargueVO criterea, String user,
			String terminal, String fecha) throws DAOException {
		ICargueDAO cargueDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			cargueDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getCargueDAO(con);
			return cargueDAO.ingresarCargue(criterea, user, terminal, fecha);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (cargueDAO != null) {
				if (!cargueDAO.isConnClosed()) {
					cargueDAO.close();
				}
			}
		}
	}

	/**
	 * 
	 * @param codeUser
	 * @param nameUser
	 * @param groupUserName
	 * @param codeLote
	 * @return
	 * @throws SQLException
	 */
	public boolean validateDelete(Long codeUser, String nameUser,
			String groupUserName, String codeLote) throws DAOException {
		ICargueDAO cargueDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			cargueDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getCargueDAO(con);
			return cargueDAO.validateDelete(codeUser, nameUser, groupUserName,
					codeLote);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (cargueDAO != null) {
				if (!cargueDAO.isConnClosed()) {
					cargueDAO.close();
				}
			}
		}
	}

	/**
	 * TODO: debe ser tx
	 * 
	 * @param codeLoteCargue
	 * @param fileData
	 * @return
	 */
	public int uploadFile(int codeLoteCargue, byte[] fileData)
			throws DAOException, UnsupportedEncodingException {
		ICargueDAO cargueDAO = null;
		Connection con;
		try {
			con = ConexionFactory.getInstance().getConnection();
			int ret;

			boolean autoCommitState = con.getAutoCommit();
			con.setAutoCommit(false);

			cargueDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getCargueDAO(con);

			UserTransaction utx = null;
			utx = TransactionUtil.getUserTransaction();
			try {
				// Inicio transaction.
				utx.begin();
				ret = cargueDAO.uploadFile(codeLoteCargue, fileData);
				// Fin - Commit transaction.
				utx.commit();
				// retornar al estado original de autocommit de la connection.
				con.setAutoCommit(autoCommitState);
			} catch (Exception e) {
				if (utx != null) {
					try {
						// Rollback si hay error.
						utx.rollback();
					} catch (SystemException sysex) {
						SUBException.logDebugError(
								"cargueService.uploadFile: ", sysex);
						throw new DAOException(sysex);
					}
				}
				throw new DAOException(e);
			}
			return ret;
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (cargueDAO != null) {
				if (!cargueDAO.isConnClosed()) {
					cargueDAO.close();
				}
			}
		}
	}

	/**
	 * 
	 * @param codeLoteCargue
	 * @param tipoCargue
	 * @param user
	 * @param terminal
	 * @param usrGroup
	 * @param usrCode
	 * @return
	 * @throws SQLException
	 */
	public boolean moveToCargarDatos(int codeLoteCargue, String tipoCargue,
			String user, String terminal, String userGroup, String userCode)
			throws DAOException {
		ICargueDAO cargueDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			cargueDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getCargueDAO(con);
			return cargueDAO.moveToCargarDatos(codeLoteCargue, tipoCargue,
					user, terminal, userGroup, userCode);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (cargueDAO != null) {
				if (!cargueDAO.isConnClosed()) {
					cargueDAO.close();
				}
			}
		}
	}

	/**
	 * TODO: tx
	 * 
	 * @param codeLoteCargue
	 * @return
	 * @throws SQLException
	 */
	public boolean deleteFile(int codeLoteCargue) throws DAOException {
		ICargueDAO cargueDAO = null;
		Connection con;
		try {
			con = ConexionFactory.getInstance().getConnection();
			boolean ret;

			boolean autoCommitState = con.getAutoCommit();
			con.setAutoCommit(false);

			cargueDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getCargueDAO(con);

			UserTransaction utx = null;
			utx = TransactionUtil.getUserTransaction();
			try {
				// Inicio transaction.
				utx.begin();
				ret = cargueDAO.deleteFile(codeLoteCargue);
				// Fin - Commit transaction.
				utx.commit();
				// retornar al estado original de autocommit de la connection.
				con.setAutoCommit(autoCommitState);
			} catch (Exception e) {
				if (utx != null) {
					try {
						// Rollback si hay error.
						utx.rollback();
					} catch (SystemException sysex) {
						SUBException.logDebugError(
								"cargueService.deleteFile: ", sysex);
						throw new DAOException(sysex);
					}
				}
				throw new DAOException(e);
			}
			return ret;
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (cargueDAO != null) {
				if (!cargueDAO.isConnClosed()) {
					cargueDAO.close();
				}
			}
		}
	}

	/**
	 * 
	 * @param lote
	 * @param tipo
	 * @return
	 * @throws SQLException
	 */
	public Collection<RegNoProcesadosVO> findRegistrosNoProcesados(String lote,
			String tipo) throws DAOException {
		ICargueDAO cargueDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			cargueDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getCargueDAO(con);
			return cargueDAO.findRegistrosNoProcesados(lote, tipo);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (cargueDAO != null) {
				if (!cargueDAO.isConnClosed()) {
					cargueDAO.close();
				}
			}
		}
	}

	/**
	 * Metodo que
	 * 
	 * @param codeLote
	 * @return
	 * @throws SQLException
	 */
	public int deleteCargue(String codeLote) throws DAOException {
		ICargueDAO cargueDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			cargueDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getCargueDAO(con);
			return cargueDAO.deleteCargue(codeLote);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (cargueDAO != null) {
				if (!cargueDAO.isConnClosed()) {
					cargueDAO.close();
				}
			}
		}
	}
}
